﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace KnightShortestPath
{
    /// <summary>
    /// This class models the movements of the knight on a chessboard 
    /// based on a specific position.
    /// </summary>
    public class Knight
    {
        /// <summary>
        /// Instance of the <see cref="KnightShortestPath.Node"/> class that represents the 
        /// current position of the knight on the chessboard
        /// </summary>
        private Node position;

        /// <summary>
        /// Array of instances of the <see cref="KnightShortestPath.Node"/> class that represent the 
        /// possible next movements of the knight on the chessboard
        /// </summary>
        private Node[] nextMovement;

        /// <summary>
        /// Creates a new instance of the <see cref="KnightShortestPath.Knight"/> class.
        /// </summary>
        /// <param name="position">
        /// Position: current position of the knight on the chessboard
        /// </param>
        public Knight(Node position){
            this.position = position;
            this.nextMovement = this.CalculateNextMovement();
        }

        /// <summary>
        /// Calculates the possible options for the next movement
        /// </summary>
        /// <returns>
        /// Returns an array of instances of the <see cref="KnightShortestPath.Node"/> 
        /// class that represent the possible next movements.
        /// </returns>
        private Node[] CalculateNextMovement() {
            Node[] movements = new Node[8];

            // Instantiates each node in the array of the movements and sets the value as is 
            // in the parent to calculate the arithmetic for the next movement
            for (int i = 0; i < 8; i++)
            {
                movements[i] = new Node(this.position.Row,this.position.Col);
            }

            // Calculates the arithmetic options for the next movement
            movements[0].Row -= 2; movements[0].Col -= 1;
            movements[1].Row -= 2; movements[1].Col += 1;
            movements[2].Row -= 1; movements[2].Col -= 2;
            movements[3].Row -= 1; movements[3].Col += 2;
            movements[4].Row += 1; movements[4].Col -= 2;
            movements[5].Row += 1; movements[5].Col += 2;
            movements[6].Row += 2; movements[6].Col -= 1;
            movements[7].Row += 2; movements[7].Col += 1;

            // Validates that each calculated position be between 0 and 7
            for (int i = 0; i < movements.GetLength(0); i++)
            {
                if (movements[i].Row < 0 || movements[i].Row >= 8 ||
                    movements[i].Col < 0 || movements[i].Col >= 8)
                {
                    movements[i] = null;
                }
            }
            return movements;
        }

        /// <summary>
        /// Position Property: Gets or Sets the value of position.
        /// </summary>
        public Node Position
        {
            get { return position; }
            set 
            { 
                position = value;
                nextMovement = this.CalculateNextMovement();
            }
        }

        /// <summary>
        /// NextMovement Property: Gets the value of the next movement.
        /// </summary>
        public Node[] NextMovement
        {
            get { return nextMovement; }
        }

    }
}
